package models

import (
	"errors"
	"fmt"
	"git.inedcn.com/ined/cmn"
	"rongyy/src/app"
	"rongyy/src/middlewares"
	"time"
)

type RegisterModel struct {
	Id               int64        `xorm:"pk autoincr" json:"id"`
	RegisterNo       string       `json:"register_no"`           // 生成的订单号
	OrderSn          string       `json:"order_sn"`              // 状态 0启用 1停用
	Fee              string       `json:"fee"`                   // 缴费费用
	PatientId        string       `json:"patient_id"`            // 0 默认值 1删除
	RegInfo          RegInfo      `json:"reg_info" xorm:"json"`  // 备注
	LockInfo         LockInfo     `json:"lock_info" xorm:"json"` // 创建时间
	RefundSn         string       `json:"refund_sn"`             // 创建人
	HisTradeNo       string       `json:"his_trade_no"`
	AdmNo            string       `json:"adm_no"`
	Status           string       `json:"status"`                    // 0 待支付，1挂号成功，-1退号，-2退号退费
	PayStatus        string       `json:"pay_status"`                // 0 创建 -1支付失败 1支付中 2支付成功
	UpdatedBy        string       `json:"updated_by"`                //callback updated by
	CreatedAt        cmn.JsonTime `xorm:"created" json:"created_at"` // 创建时间
	UpdatedAt        cmn.JsonTime `xorm:"updated" json:"updated_at"` // 更新时间
	Hospital         string       `json:"hospital" xorm:"-"`
	Remark           string       `json:"remark"`
	HisFeedback      string       `json:"his_feedback"`
	HisCode          string       `json:"his_code"`
	LockQueueNo      string       `json:"lock_queue_no"`
	ScheduleItemCode string       `json:"schedule_item_code"`
	AdmDoc           string       `json:"adm_doc"`
	AdmDate          string       `json:"adm_date"`
	AdmTime          string       `json:"adm_time"`
	TransactionId    string       `json:"transaction_id"`
	AdmitAddress     string       `json:"admit_address"`
	TimeRange        string       `json:"time_range"`
	AdmitRange       string       `json:"admit_range"`
	SeqCode          string       `json:"seq_code"`
	Openid           string       `json:"openid" xorm:"openid"`
	DoctorName       string       `json:"doctor_name"`
	DeptName         string       `json:"dept_name"`
	PatientName      string       `json:"patient_name"`
	AppOrderCode     string       `json:"app_order_code"`
	InvoiceStr       string       `json:"invoice_str"`
	PayWay string `json:"pay_way"`
}

type BranchModel struct {
	Id        int    `json:"id"`
	HospName  string `json:"hospName" xorm:"hosp_name"`
	Alias     string `json:"alias"`
	Address   string `json:"address"`
	Mobile    string `json:"mobile"`
	Mobile1   string `json:"mobile1"`
	Des       string `json:"des"`
	Latitude  string `json:"latitude"`
	Longitude string `json:"longitude"`
	Scale     string `json:"scale"`
}

type ReqRegError struct {
	Limit     int    `json:"limit"`
	Offset    int    `json:"offset"`
	PatientId string `json:"patient_id"`
	Hospital  string `json:"hospital"`
	OrderSn   string `json:"order_sn"`
}

type LockInfo struct {
	TradeCode        string `json:"trade_code"`
	ResultCode       string `json:"result_code"`        // 生成的订单号
	ResultContent    string `json:"result_content"`     // 状态 0启用 1停用
	LockQueueNo      string `json:"lock_queue_no"`      // 0 默认值 1删除
	ScheduleItemCode string `json:"schedule_item_code"` // 备注
	AdmDoc           string `json:"adm_doc"`            // 创建时间
	AdmDate          string `json:"adm_date"`           // 创建人
	AdmTime          string `json:"adm_time"`           // 创建人
	RegFee           string `json:"reg_fee"`            // 创建时间
	TransactionId    string `json:"transaction_id"`     // 更新时间
	Hospital         string `json:"hospital" xorm:"-"`
}

type DoctorInfo struct {
	Id       string `json:"id"`
	Sn       string `json:"sn"`
	Descript string `json:"descript"` // 医生简介
	Image    string `json:"image"`    // 头像图片
	NewImage string `json:"new_image"`
	Hospital string `json:"hospital" xorm:"-"`
}

type RegInfo struct {
	PatName    string `json:"pat_name"`
	Department string `json:"department"` // 生成的订单号
	Doctor     string `json:"doctor"`     // 状态 0启用 1停用
	PatDate    string `json:"pat_date"`   // 0 默认值 1删除
	RegFee     string `json:"reg_fee"`    // 备注
	Hospital   string `json:"hospital" xorm:"-"`
}

type ReqFindByRegNo struct {
	RegisterNo string `json:"register_no"  binding:"required"`
	AdmNo      string `json:"adM_no"`
	OrderSn    string `json:"order_sn"`
	Hospital   string `json:"hospital" xorm:"-"`
}

type ReqByPatientId struct {
	PatientId string `json:"patient_id"  binding:"required"`
	Hospital  string `json:"hospital" xorm:"-"`
}

type ReqSaveRefund struct {
	AdmNo      string `json:"adm_no"`
	RefundSn   string `json:"refund_sn"`
	HisTradeNo string `json:"his_trade_no"`
	Hospital   string `json:"hospital" xorm:"-"`
}

type RespScheduleByName struct {
	DoctorName     string `json:"doctor_name"`
	DepartmentCode string `json:"department_code"`
	DepartmentName string `json:"department_name"`
	RegFee         string `json:"reg_fee"`
	Img            string `json:"img"`
	Desc           string `json:"desc"`
	DoctorSessType string `json:"doctor_sess_type"`
}

type ReqScheduleTimeInfoRange struct {
	Codes []string `json:"codes"`
}

func (rm *RegisterModel) TableName() string {
	return "reg_orders"
}

func (rm *RegisterModel) String() string {
	return fmt.Sprintf("userid")
}

func (rm *RegisterModel) Create(reg *RegisterModel) error {
	_, err := app.DB().Insert(reg)
	if err != nil {
		return err
	}
	return nil
}

func (rm *RegisterModel) FindByRegNo(regNo string, hospital string) (*RegisterModel, bool, error) {
	reg := new(RegisterModel)
	has, err := app.DB().Where("register_no = ?", regNo).Get(reg)
	if err != nil {
		return nil, has, err
	}
	return reg, has, nil
}

func (rm *RegisterModel) FindByOrderSn(orderSn string) (*RegisterModel, bool, error) {
	reg := new(RegisterModel)
	has, err := app.DB().Where("order_sn = ?", orderSn).Limit(1).Get(reg)
	fmt.Println(has)
	if err != nil {
		return nil, has, err
	}
	return reg, has, nil
}

func (rm *RegisterModel) FindByOrderSnAndTranId(orderSn string, tranId string) (*RegisterModel, bool, error) {
	reg := new(RegisterModel)
	has, err := app.DB().Where("order_sn = ? and transaction_id", tranId).Limit(1).Get(reg)
	if err != nil {
		return nil, has, err
	}
	return reg, has, nil
}

func (rm *RegisterModel) Cancel(regNo string, hospital string) error {
	reg := new(RegisterModel)
	reg.Status = "-1"
	_, err := app.DB().Where("register_no = ?", regNo).Cols("status").Update(reg)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) RefundCancel(regNo string, hospital string) error {
	reg := new(RegisterModel)
	reg.Status = "-2"
	_, err := app.DB().Where("register_no = ?", regNo).Cols("status").Update(reg)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) Confirm(regNo string, hospital string) error {
	reg := new(RegisterModel)
	_, err := app.DB().Where("register_no = ?", regNo).Get(reg)
	reg.Status = "1"
	reg.PayStatus = "2"
	_, err = app.DB().ID(reg.Id).Cols("status", "pay_status", "updated_at").Update(reg)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) FindUnpaid(patientId string, hospital string) ([]RegisterModel, error) {
	//reg := &RegisterModel{}
	regs := make([]RegisterModel, 0)
	local, _ := time.LoadLocation("Asia/Shanghai")
	t := time.Now().In(local).Format("2006-01-02 15:04:05")
	_, err := app.DB().Where("patient_id = ? and status = 0 and  TIMESTAMPDIFF(MINUTE, created_at, ?) > -2  and TIMESTAMPDIFF(MINUTE, created_at, ?) < 9", patientId, t, t).FindAndCount(&regs)
	if err != nil {
		return nil, err
	}
	return regs, err
}

func (rm *RegisterModel) FindByAdmNo(admNo string) (*RegisterModel, bool, error) {
	reg := &RegisterModel{}
	has, err := app.DB().Where("adm_no = ?", admNo).Get(reg)
	if err != nil {
		return nil, has, err
	}
	return reg, has, err
}

func (rm *RegisterModel) UpdateRegRefund(admNo string, refundSn string, hospital string) error {
	reg := &RegisterModel{}
	reg.RefundSn = refundSn
	reg.Status = "-2"
	_, err := app.DB().Where("adm_no = ? and status = 1", admNo).Cols("refund_sn", "status").Update(reg)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) UpdateTheHisTradeNo(admNo string, hisTradeNo string, hospital string) error {
	reg := &RegisterModel{}
	reg.HisTradeNo = hisTradeNo
	_, err := app.DB().Where("adm_no = ?", admNo).Cols("his_trade_no").Update(reg)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) UpdateTheRegAdmNo(registerNo string, admNo string, hospital string) error {
	reg := &RegisterModel{}
	reg.AdmNo = admNo
	reg.Status = "1"
	reg.PayStatus = "2"
	_, err := app.DB().Where("register_no = ?", registerNo).Cols("adm_no", "status", "pay_status", "updated_at").Update(reg)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) UpdateRegOrderSn(registerNo string, orderSn string, payStatus string, hospital string) error {
	reg := &RegisterModel{}
	reg.OrderSn = orderSn
	reg.PayStatus = payStatus
	_, err := app.DB().Where("register_no = ?", registerNo).Update(reg)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) SaveRegRefundM(orderSn string, refundSn string, hospital string) error {
	reg := &RegisterModel{}
	reg.RefundSn = refundSn
	reg.Status = "-2"
	_, err := app.DB().Where("order_sn = ? and status = 1", orderSn).Cols("refund_sn", "status").Update(reg)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) SaveRegRefundOrderSnM(orderSn string, refundSn string, hospital string) error {
	reg := &RegisterModel{}
	reg.RefundSn = refundSn
	_, err := app.DB().Where("order_sn = ? and status = 1", orderSn).Cols("refund_sn").Update(reg)
	if err != nil {
		return err
	}
	return err
}

// 支付失败
func (rm *RegisterModel) CancelPayingRegisterPayStatusM(regNo string, hospital string) error {
	reg := &RegisterModel{}
	reg.PayStatus = "-1"
	_, err := app.DB().Where("register_no = ? and pay_status = 1 and status = 0", regNo).Cols("pay_status", "updated_at").Update(reg)
	if err != nil {
		return err
	}
	return err
}

// 支付失败
func (rm *RegisterModel) CancelPayingRegByOrderSn(orderSn string, hospital string) error {
	reg := &RegisterModel{}
	reg.PayStatus = "-1"
	_, err := app.DB().Where("order_sn = ? and pay_status = 1 and status = 0", orderSn).Cols("pay_status", "updated_at").Update(reg)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) GetDoctorByIdM(id string, hospital string) (*DoctorInfo, bool, error) {
	doc := &DoctorInfo{}
	has, err := app.DB().Table("sys_employee").Where("sn = ?", id).Get(doc)
	if err != nil {
		return nil, false, err
	}
	return doc, has, err
}

// 一个月退号记录
// select * from registered_orders where status = -2  and DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= created_at
// select * from registered_orders where status = 1 and patient_id = 0000422604 and  to_days(created_at) = to_days(now())

func (rm *RegisterModel) Restriction(patientId string, hospital string) (bool, error) {
	res := false
	rms := make([]RegisterModel, 0)
	total, err := app.DB().Table("registered_orders").Where("status = -2 and DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= created_at and patient_id = ?", patientId).FindAndCount(&rms)
	if err != nil {
		return true, err
	}

	if total > 2 {
		res = true
	} else {
		newrms := make([]RegisterModel, 0)
		t := time.Now().Unix() - 15*60
		fmt.Println("res-=-==", t)
		total, err = app.DB().Table("registered_orders").Where("status < 1 and patient_id = ? and to_days(created_at) = to_days(now()) and unix_timestamp(created_at) < ?", patientId, t).FindAndCount(&newrms)
		if err != nil {
			return true, err
		}
		fmt.Println("total-=-==", total)
		if total > 2 {
			res = true
		}
	}
	fmt.Println("res-=-==", res)
	return res, err
}

func (rm *RegisterModel) UpdateCallbackUpdatedBy(orderSn string, updatedBy string, hospital string) error {
	reg := &RegisterModel{}
	reg.UpdatedBy = updatedBy
	_, err := app.DB().Where("order_sn = ?", orderSn).Cols("updated_by").Update(reg)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) RegPayCallback(orderSn string, updatedBy string, hospital string) (*RegisterModel, error) {
	reg := &RegisterModel{}
	has, err := app.DB().Where("order_sn = ?", orderSn).Get(reg)
	if !has {
		return nil, errors.New("没有符合条件的订单")
	}
	if len(reg.UpdatedBy) > 0 {
		return nil, errors.New("订单已更新")
	}
	reg.UpdatedBy = updatedBy
	reg.PayStatus = "2"
	_, err = app.DB().Where("order_sn = ?", orderSn).Cols("updated_by", "pay_status", "updated_at").Update(reg)
	if err != nil {
		fmt.Println("err====", err)
		return nil, err
	}
	return reg, err
}

func (rm *RegisterModel) QueryUnconfirmOrder() ([]RegisterModel, int64, error) {
	regs := make([]RegisterModel, 0)
	local, _ := time.LoadLocation("Asia/Shanghai")
	t := time.Now().In(local).Format("2006-01-02 15:04:05")
	total, err := app.DB().Where("status = 'locked' and pay_status = 'paying' and TIMESTAMPDIFF( MINUTE, created_at, ? ) < 6 and TIMESTAMPDIFF( MINUTE, created_at, ? ) > 2", t).Limit(999, 0).FindAndCount(&regs)
	if err != nil {
		return nil, 0, err
	}
	return regs, total, err
}

func (rm *RegisterModel) UpdateRegRemark(orderSn string, remark string, hospital string) error {
	reg := &RegisterModel{}
	reg.Remark = remark
	_, err := app.DB().Where("order_sn = ?", orderSn).Cols("remark").Update(reg)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) UpdateHisFeedback(req *RegisterModel) error {
	_, err := app.DB().Where("order_sn = ?", req.OrderSn).Cols("his_feedback", "his_code").Update(req)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) QueryErrorOrder(req *ReqRegError) ([]RegisterModel, int64, error) {
	regs := make([]RegisterModel, 0)
	//local, _ := time.LoadLocation("Asia/Shanghai")
	//t := time.Now().In(local).Format("2006-01-02 15:04:05")
	s := app.DB().Table("registered_orders")
	if req.PatientId != "" {
		pid := fmt.Sprintf("%%%s%%", req.PatientId)
		s.Where("patient_id = ?", pid)
	}
	total, err := s.Where("status in (0, -1) and pay_status = 2").Limit(req.Limit, req.Offset).Desc("created_at").FindAndCount(&regs)
	if err != nil {
		return nil, 0, err
	}
	return regs, total, err
}

func (rm *RegisterModel) LockOrderList(pid string) ([]RegisterModel, int64, error) {
	regs := make([]RegisterModel, 0)
	//local, _ := time.LoadLocation("Asia/Shanghai")
	//t := time.Now().In(local).Format("2006-01-02 15:04:05")
	s := app.DB().Where("patient_id = ?", pid)
	total, err := s.Where("status = 'locked' and pay_status in ('paying', '', 'cancelled') and created_at >= DATE_SUB(NOW(), INTERVAL 10 MINUTE)").Limit(99, 0).Desc("created_at").FindAndCount(&regs)
	if err != nil {
		return nil, 0, err
	}
	return regs, total, err
}

// LockOrderList
//
//	@Description: 取消锁号
//	@receiver rm
//	@param pid
//	@return []RegisterModel
//	@return int64
//	@return error
func (rm *RegisterModel) UnlockReg() error {
	_, err := app.DB().Where("transaction_id = ?", rm.TransactionId).Cols("status").Update(rm)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) ConfirmReg() error {
	_, err := app.DB().Where("transaction_id = ?", rm.TransactionId).Cols("status", "pay_status", "admit_range", "seq_code", "time_range", "admit_address", "adm_no", "his_trade_no", "updated_by").Update(rm)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) ConfirmZjyy() error {
	_, err := app.DB().Where("app_order_code = ?", rm.AppOrderCode).Cols("status", "pay_status", "admit_range", "seq_code", "time_range", "admit_address", "adm_no", "his_trade_no", "updated_by").Update(rm)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) FindOrderByAppOrderCode(app_order_code string) (*RegisterModel, bool, error) {
	nrm := &RegisterModel{}
	has, err := app.DB().Where("app_order_code = ?", app_order_code).Get(nrm)
	if err != nil {
		middlewares.Logger.Println("FindByTransactionId fail ", err)
		return nil, has, err
	}
	return nrm, has, err
}

// FindByTransactionId
//
//	@Description: 通过TransactionId查找
//	@receiver rm
//	@param transactionId
//	@return *RegisterModel
//	@return bool
//	@return error
func (rm *RegisterModel) FindByTransactionId(transactionId string) (*RegisterModel, bool, error) {
	reg := &RegisterModel{}
	has, err := app.DB().Where("transaction_id = ?", transactionId).Limit(1).Desc("created_at").Get(reg)
	if err != nil {
		middlewares.Logger.Println("FindByTransactionId fail ", err)
		return nil, has, err
	}
	return reg, has, err
}

/*查询60秒内待支付订单*/
func (rm *RegisterModel) FindByTransactionIdInOneMin(transactionId string) (*RegisterModel, bool, error) {
	reg := &RegisterModel{}
	//local, _ := time.LoadLocation("Asia/Shanghai")
	//t := time.Now().In(local).Format("2006-01-02 15:04:05")
	s := app.DB()
	has, err := s.Where("transaction_id = ? and created_at >= DATE_SUB(NOW(), INTERVAL 1 MINUTE)", transactionId).Get(reg)
	if err != nil {
		middlewares.Logger.Println("FindByTransactionId fail ", err)
		return nil, has, err
	}
	return reg, has, err
}

func (rm *RegisterModel) Paying() error {
	_, err := app.DB().Where("transaction_id = ?", rm.TransactionId).Cols("order_sn", "pay_status", "openid","pay_way").Update(rm)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) PayingFail() error {
	_, err := app.DB().Where("transaction_id = ?", rm.TransactionId).Cols("order_sn", "pay_status", "openid", "remark").Update(rm)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) CancelPaying() error {
	_, err := app.DB().Where("transaction_id = ?", rm.TransactionId).Cols("pay_status").Update(rm)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) UpdateRefund() error {
	_, err := app.DB().Where("order_sn = ?", rm.OrderSn).Cols("remark", "pay_status", "refund_sn").Update(rm)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) UpdatePayStatus() error {
	_, err := app.DB().Where("transaction_id = ?", rm.TransactionId).Cols("pay_status").Update(rm)
	if err != nil {
		return err
	}
	return err
}

func (rm *RegisterModel) QueryByScheduleItemCode(code string) ([]RegisterModel, int64, error) {
	rms := make([]RegisterModel, 0)
	total, err := app.DB().Where("schedule_item_code = ? and pay_status='paid' and status='confirm'", code).FindAndCount(&rms)
	if err != nil {
		return nil, 0, err
	}
	return rms, total, err
}

// 处理带单边账退费（4.25）
func (rm *RegisterModel) Dbz() ([]RegisterModel, int64, error) {
	rms := make([]RegisterModel, 0)
	total, err := app.DB().Where("pay_status='paying' and created_at>'2024-04-25 07:00:00' and created_at<'2024-04-25 10:00:00'").FindAndCount(&rms)
	if err != nil {
		return nil, 0, err
	}
	return rms, total, err
}

func (rm *RegisterModel) GetBranch() ([]BranchModel, error) {
	pre := make([]BranchModel, 0)
	app.DB().Table("branch").Find(&pre)
	return pre, nil
}
